package kt.com.bilin.coin.utils;


import java.util.ArrayList;
import java.util.List;

import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;

public class FragmentChangeManager {
    private FragmentManager mFragmentManager;
    private int mContainerViewId;
    /**
     * Fragment切换数组
     */
    private List<Fragment> mFragments;
    /**
     * 当前选中的Tab
     */
    private int mCurrentTab;

    public FragmentChangeManager(FragmentManager fm, int containerViewId) {
        this.mFragmentManager = fm;
        this.mContainerViewId = containerViewId;
        this.mFragments = new ArrayList<>();
    }

    public FragmentChangeManager(FragmentManager fm, int containerViewId, ArrayList<Fragment> fragments) {
        this(fm, containerViewId, fragments, 0);
    }

    public FragmentChangeManager(FragmentManager fm, int containerViewId, ArrayList<Fragment> fragments, int index) {
        this.mFragmentManager = fm;
        this.mContainerViewId = containerViewId;
        this.mFragments = fragments;
        initFragments(index);
    }


    /**
     * 初始化fragments
     */
    private void initFragments(int index) {
        Fragment fragment;
        String tag;
        for (int i = 0; i < mFragments.size(); i++) {
            fragment = mFragments.get(i);
            tag = String.format("%s-%s", fragment.getClass().getName(), i);
            Fragment fragmentByTag = mFragmentManager.findFragmentByTag(tag);
            if (fragmentByTag != null) {
                mFragments.set(i, fragmentByTag);
                mFragmentManager.beginTransaction().hide(fragmentByTag).commitAllowingStateLoss();
            } else {
//                mFragmentManager.beginTransaction().add(mContainerViewId, fragment, tag).hide(fragment).commitAllowingStateLoss();
            }
        }
        setFragments(index);
    }

    public void addFragment(Fragment fragment) {
        mFragments.add(fragment);
        int index = mFragments.size() - 1;
        String tag = String.format("%s-%s", fragment.getClass().getName(), index);
        Fragment fragmentByTag = mFragmentManager.findFragmentByTag(tag);
        FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
        if (fragmentByTag != null) {
            fragmentTransaction.remove(fragmentByTag);
//            mFragments.set(index, fragmentByTag);
//            mFragmentManager.beginTransaction().hide(fragmentByTag).commitAllowingStateLoss();
        } else {
            fragmentTransaction.add(mContainerViewId, fragment, tag).hide(fragment).commitAllowingStateLoss();
        }
    }

    public void setFragment(Fragment fragment) {
        for (int i = 0; i < mFragments.size(); i++) {
            if (fragment.getClass().isAssignableFrom(mFragments.get(i).getClass()))
                setFragments(i);
        }
    }

    public void hiddenFragment(Fragment fragment) {
        if (!fragment.isHidden())
            mFragmentManager.beginTransaction().hide(fragment).commitAllowingStateLoss();
    }

    /**
     * 界面切换控制
     */
    public void setFragments(int index) {
        if (index == -1 || index >= mFragments.size())
            return;
        FragmentTransaction ft = mFragmentManager.beginTransaction();
        for (int i = 0; i < mFragments.size(); i++) {
            Fragment fragment = mFragments.get(i);
            String tag = String.format("%s-%s", fragment.getClass().getName(), index);
            if (i == index) {
                if (!fragment.isAdded()) {
                    mFragmentManager.beginTransaction().add(mContainerViewId, fragment, tag).commitAllowingStateLoss();
                    mFragmentManager.executePendingTransactions();
                } else {
                    ft.show(fragment);
                }
            } else {
                if (fragment.isAdded() && !fragment.isHidden()) {
                    ft.hide(fragment);
                }
            }
        }
        ft.commitAllowingStateLoss();
        mCurrentTab = index;
    }

    public void removeAll() {
        FragmentTransaction ft = mFragmentManager.beginTransaction();
        for (int i = 0; i < mFragments.size(); i++) {
            ft.remove(mFragments.get(i));
        }
        ft.commitAllowingStateLoss();
    }

    public int onAttachFragment(Fragment fragment) {
        if (fragment != null && mFragments != null) {
            for (int i = 0; i < mFragments.size(); i++) {
                if (mFragments.get(i).getClass().isAssignableFrom(fragment.getClass())) {
                    mFragments.set(i, fragment);
                    String tag = String.format("%s-%s", fragment.getClass().getName(), i);
                    mFragmentManager.beginTransaction().add(mContainerViewId, fragment, tag).hide(fragment).commitAllowingStateLoss();
                    return i;
                }
            }
        }
        return -1;
    }

    public int getCurrentTab() {
        return mCurrentTab;
    }

    public Fragment getCurrentFragment() {
        return mFragments.get(mCurrentTab);
    }

    public int getSize() {
        return mFragments.size();
    }

    public <T extends Fragment> T getCurrentFragment(Class<T> clz) {
        return (T) mFragments.get(mCurrentTab);
    }

    public <T extends Fragment> T getFragment(int position, Class<T> clz) {
        return (T) mFragments.get(position);
    }

    public <T extends Fragment> T getFragment(Class<T> clz) {
        if (clz == null) return null;
        for (int i = 0; i < mFragments.size(); i++) {
            if (clz.isAssignableFrom(mFragments.get(i).getClass()))
                return (T) mFragments.get(i);
        }
        return null;
    }

    public List<Fragment> getFragments() {
        return mFragments;
    }
}
